home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / gcoope10.zip / GARBAGE.C < prev    next >
Text File  |  1994-07-22  |  5KB  |  207 lines

  1. /*
  2.  
  3.     garbage collection, makePerm, and s_ memory allocation shells,
  4.  
  5.               for GCOOPE Version 1.0
  6.  
  7.                 by Brian Lee Price
  8.  
  9.         Released as Public Domain   July, 1994.
  10.  
  11. */
  12.  
  13. #include <alloc.h>
  14.  
  15. #define __GARBAGE__
  16.  
  17. #include "gcstruct.h"
  18.  
  19.  
  20. /* garbage collection static variables */
  21.  
  22. static int    ErrMem=0;
  23. static int    Killed=0;
  24. static int      curNdx=0;
  25. static int    ageDcr=(int)MINDCRVAL;
  26. static int    shftVal=MAXSHIFTVAL;
  27. static long    timeVal=TIMVAL;
  28.  
  29. /* round-robin routine with adaptive features */
  30. /*
  31. FOR KERNEL USE ONLY.
  32.  
  33.     This routine has two basic modes of operation, normally it
  34.     only examines a few objects each call and the age decrement value
  35.     is (usually) low.  However in this basic mode, it is adaptive.
  36.     A time out of timeVal will slow down the routine, while an internal
  37.     out of memory error will speed up the routine.  In this mode, the
  38.     collector will ignore any objects which are not of the current
  39.     process ID.
  40.     The second mode of operation goes into effect on an out of
  41.     memory condition.  In this mode, it examines the maximum set number
  42.     of objects, decrementing the age by the maximum amount, and ignores
  43.     only a process ID of PERM_PROC_ID.
  44. */
  45.  
  46. static void garbage(void)
  47. {
  48. register int     x;
  49. register int    locDcr;
  50. int        oldDcr;
  51. int        oldShft;
  52. objectEntry *   objEnt;
  53.  
  54. if(ErrMem)
  55.    {         /* on mem err, save norm parms, goto max vals */
  56.    oldDcr=ageDcr;
  57.    ageDcr=(int)MAXDCRVAL;
  58.    oldShft=shftVal;
  59.    shftVal=MINSHIFTVAL;
  60.    }
  61. else if(--timeVal<=0)    /* otherwise check for timer time out */
  62.    {
  63.    timeVal=TIMVAL;
  64.    ageDcr-=ageDcr>>2;    /* reduce DCR by 25% */
  65.    if(ageDcr<MINDCRVAL)
  66.       {        /* if DCR bottomed out, check less often */
  67.       ageDcr=(int)(MINDCRVAL*3)/2;
  68.       shftVal+=(shftVal<(MAXSHIFTVAL))?1:0;
  69.       }
  70.    }
  71. x=(objList.maxElems)>>shftVal;
  72. x=(x<=0)?1:x;
  73. if(NULL==(objEnt=objList.listPtr)) return;
  74.  
  75. for(locDcr=ageDcr;x>0;x--,curNdx++)
  76.    {
  77.    if(curNdx>=objList.maxElems) curNdx=0;
  78.    if(NULL==(objEnt[curNdx].objDef)) continue;
  79.    else if((curProcID!=objEnt[curNdx].procID && !ErrMem)
  80.     || (objEnt[curNdx].procID==PERM_PROC_ID)) continue;
  81.    else if(objEnt[curNdx].lastAcc>locDcr) objEnt[curNdx].lastAcc-=locDcr;
  82.    else
  83.        {
  84.        g(Kill)((object) curNdx);
  85.        Killed=1;
  86.        }
  87.    }
  88. if(ErrMem)         /* if in memory error mode reset to normal parms */
  89.    {
  90.    if(Killed)
  91.       {
  92.       ageDcr=oldDcr+(oldDcr>>1);    /* increase norm DCR by 50% */
  93.       shftVal=oldShft;
  94.       if(ageDcr>MAXDCRVAL)
  95.      {                /* if DCR MAXED, check more often */
  96.      ageDcr=(int)MAXDCRVAL/2;
  97.      shftVal-=(shftVal>MINSHIFTVAL)?1:0;
  98.      }
  99.       }
  100.    else
  101.       {
  102.       ageDcr=oldDcr;
  103.       shftVal=oldShft;
  104.       }
  105.    ErrMem=0;
  106.    }
  107. }
  108.  
  109.  
  110. /*
  111. AVAILABLE FOR EXTERNAL USE.
  112.  
  113.     This routine makes an object permanent with respect to the garbage
  114.     collector.  After this call is made, g(Kill)(object,...) must be
  115.     called in order to remove the object from memory.
  116. */
  117.  
  118. stat makePerm(object instance)
  119. {
  120. objectEntry *   objEnt;
  121.  
  122. if(instance<0) return FUNCOKAY;
  123. if((NULL==(objEnt=getObject((tag) instance)))
  124.     || (NULL==objEnt->objDef)) return FUNCFAIL;
  125. objEnt->procID=PERM_PROC_ID;
  126. return FUNCOKAY;
  127. }
  128.  
  129. /*
  130. FOR KERNEL USE ONLY.
  131.  
  132.     This routine fakes a memory error if a list runs out of available
  133.     elements.  Thus the garbage collector will kill off some of the older
  134.     instances to free up available slots.
  135. */
  136.  
  137. void outOfElems(void)
  138. {
  139. int x;
  140.  
  141. ErrMem=1;
  142. Killed=0;
  143. for(x=MAX_ERR_TRY;x>0 && !Killed;x--) garbage();
  144. if(!Killed) g(Err)(Object,Object,gcerrmsg[ERR_OUT_OF_MEM]);
  145. }
  146.  
  147.  
  148.  
  149. /*
  150. AVAILABLE FOR EXTERNAL USE.
  151.  
  152.     This is the standard library calloc shell, note that it works
  153.    directly with the garbage collector and as long as the default error
  154.    routine aborts the program, it NEVER returns NULL.
  155. */
  156.  
  157. void * s_calloc(unsigned nitems, unsigned size)
  158. {
  159. void * retVal;
  160.  
  161. garbage();
  162. while(NULL==(retVal=calloc(nitems,size))) outOfElems();
  163. return retVal;
  164. }
  165.  
  166. /*
  167. AVAILABLE FOR EXTERNAL USE.
  168.  
  169.     This routine is here mostly for completeness, however note
  170.     that when upgrading to an aftermarker heap manager only the shell
  171.     routines in this module need to be modified.
  172.  
  173. */
  174.  
  175. void s_free(void * block)
  176. {
  177. if(block!=NULL) free(block);
  178. }
  179.  
  180.  
  181. void * s_malloc(unsigned size)
  182. {
  183. void * retVal;
  184.  
  185. garbage();
  186. while(NULL==(retVal=malloc(size))) outOfElems();
  187. return retVal;
  188. }
  189.  
  190.  
  191. /*
  192. AVAILABLE FOR EXTERNAL USE.
  193.  
  194.     See s_calloc and s_free for notes.
  195. */
  196.  
  197. void * s_realloc(void * block, unsigned newSize)
  198. {
  199. void * retVal;
  200.  
  201. garbage();
  202. while(NULL==(retVal=realloc(block,newSize))) outOfElems();
  203. return retVal;
  204. }
  205.  
  206.  
  207.